from CDB import CDB
from Reorder_Buffer import Reorder_Buffer
from Resev_Station import ReservationStation
from Inst_queue import Instr_queue
from FP_Register import FPRegisters
from Execute_Unit import FPAdder, FPMultiplier
from Address_Unit import AddressUnit
from Memory_Unit import MemoryUnit


class Simulator:
    def __init__(self, instruct_file_path):
        self.fp_registers = FPRegisters()
        self.cdb = CDB()
        self.fp_adder = FPAdder(self.cdb)
        self.fp_multiplier = FPMultiplier(self.cdb)
        self.memory_unit = MemoryUnit(self.cdb)
        self.address_unit = AddressUnit(self.cdb)
        self.reorder_buffer = Reorder_Buffer(9, self.fp_registers, self.cdb)
        self.reservation_station = ReservationStation(self.cdb, self.fp_registers, self.fp_adder, self.fp_multiplier, self.memory_unit, self.address_unit, self.reorder_buffer)
        self.instr_queue = Instr_queue(instruct_file_path, self.reservation_station, self.reorder_buffer)
        self.clock = 0

    def runing(self):
        while self.instr_queue.has_more_instructions() or not self.reorder_buffer.is_empty():
            print(f"---------------------------Clock Cycle: {self.clock+1}---------------------------\n")
            self.cdb.clear()
            self.reorder_buffer.commit()
            self.reservation_station.execute_entries()
            self.reorder_buffer.check_cdb()
            self.reservation_station.update_operands()
            self.instr_queue.dispatch_instruction()
            


            self.clock += 1
            self.reorder_buffer.display()
            print()
            self.reservation_station.display()
            print()
            self.fp_registers.display_registers()
            print("\n\n")

            if self.clock > 100:
                break

